package me.ingxin.android.tools

import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.InputStream
import java.security.DigestInputStream
import java.security.MessageDigest
import java.util.zip.ZipInputStream

/**
 * 获取文件md5值
 * @return 文件md5值，失败返回null
 */
fun File.md5(): String? {
    if (!exists()) {
        return null
    }
    try {
        val md5InputStream = FileInputStream(this)
        val digestInputStream = DigestInputStream(md5InputStream, MessageDigest.getInstance("MD5"))
        val byteBuffer = ByteArray(2 * 1024)
        while (digestInputStream.read(byteBuffer) > 0) {
            //等待读取结束
        }
        return digestInputStream.messageDigest?.digest()?.let { Hex.encode(it) }
    } catch (ex: Exception) {
        ex.printStackTrace()
    }
    return null
}

/**
 * 解压文件
 * @param outputPath 解压后的路径
 * @return true解压成功，false解压失败
 */
fun File.unzip(outputPath: String): Boolean {
    val ins = FileInputStream(this)
    return ins.unzip(outputPath)
}

/**
 * 解压文件
 * @param outputPath 解压后的路径
 * @return true解压成功，false解压失败
 */
fun InputStream.unzip(outputPath: String): Boolean {
    val ins = ZipInputStream(this)
    var entry = ins.nextEntry
    val buffer = ByteArray(1024 * 1024)
    try {
        while (entry != null) {
            val name = entry.name
            if (name?.contains("../") == true) {
                continue
            }
            val fileName = "${outputPath}${File.separator}$name"
            val file = File(fileName)
            if (entry.isDirectory) {
                if (!file.exists()) {
                    file.mkdirs()
                }
            } else {
                if (!file.exists()) {
                    file.absoluteFile.parentFile?.mkdirs()
                    file.createNewFile()
                }
                val out = FileOutputStream(file)
                var len = ins.read(buffer)
                while (len > 0) {
                    // 从缓冲区（0）位置写入（字节）字节
                    out.write(buffer, 0, len)
                    out.flush()
                    len = ins.read(buffer)
                }
                out.close()
            }
            entry = ins.nextEntry
        }
        ins.close()
        return true
    } catch (ex: Exception) {
        ex.printStackTrace()
        ins.close()
    }
    return false
}

/**
 * 删除文件夹
 * @throws [Exception]
 * @return true删除成功，false删除失败
 */
fun File.deleteAll(): Boolean {
    if (!this.exists()) {
        return true
    }
    if (this.isFile) {
        return delete()
    }
    val list = listFiles()
    if (list == null || list.isEmpty()) {
        return delete()
    }
    for (f in list) {
        if (f != null && !f.deleteAll()) {
            return false
        }
    }
    return delete()
}